
import * as Y from 'yjs'
import { WebsocketProvider } from 'y-websocket'
import { MonacoBinding } from 'y-monaco'
import * as monaco from '../../../node_modules/monaco-editor/esm/vs/editor/editor.main.js'
import React, { useEffect, useState } from 'react'
import "./LiveRoomCode.scss"
import { initDrag } from '../../utils'
import { Button,Form,Select, } from 'antd'
import { useDispatch } from 'react-redux'
import ReactLoading from "react-loading";
import {javaCode,javascriptCode,cppCode} from "../../utils/codeSplit"
const { Option } = Select;


export default function LiveRoomCode(props) {
    const [editor,setEditor] = useState(null)
    const show = props.state.codeEdit;
    const dispatch = props.dispatcher;
    const roomInfo = props.state.roomInfo;
    const codeType = props.state.codeType;
    const codeResult = props.state.codeResult;
    const pending = props.state.pending;
    let ytext;
    useEffect(()=>{
      return initDrag("monaco-editor");
    },[]);
    useEffect(()=>{
        try {
            if(!roomInfo.yjsAddr)return ;
            const ydoc = new Y.Doc()
            const provider = new WebsocketProvider(roomInfo.yjsAddr, roomInfo.yjsRoomName, ydoc)
            ytext = ydoc.getText('monaco');
            dispatch({
                type: "setYtext",
                ytext
            });
            if(!editor) {
                const tem_e = monaco.editor.create(document.getElementById('monaco-editor'), {
                    value: '',
                    language: codeType,
                    // theme: 'vs-dark'
                });
                setEditor(tem_e);
                return ;
            }
            // 绑定
            const monacoBinding = new MonacoBinding(ytext, /** @type {monaco.editor.ITextModel} */ (editor.getModel()), new Set([editor]), provider.awareness)
            return () => {
                ydoc.destroy();
                provider.disconnect();
            }
        }catch(e) {
            console.log(e);
        }

    },[roomInfo,editor]);




    const onFinishCodeType = (rule,values) => {
        console.log(values);
        dispatch({
            type: "setCodeType",
            codeType: values
        })
        return Promise.resolve();
    }

    useEffect(()=>{
        if(editor) {
            monaco.editor.setModelLanguage(editor.getModel(),codeType);
        }
    },[codeType]);


    const initCode = () => {
        switch (codeType) {
            case "javascript":
                editor.getModel().setValue(javascriptCode);
                break;
            case "java":
                editor.getModel().setValue(javaCode);
                break;
            case "cpp":
                editor.getModel().setValue(cppCode);
                break;
            default :
            break;
        }
    }
    const parseResult = (result) => {
        return result.replaceAll("\n","<br/>");
    }
    return (
        <div className='LiveRoomCode-container' style={{
            opacity: show?1:0,
            zIndex: show?999:-999,
        }}>
            <div id="monaco-editor" className='monaco-editor'>
                <div className='codeHeader' id='codeHeader'>
                    Shared Code Editor! by: lrj
                    <Form
                        className='choose'
                        name="register"
                        scrollToFirstError
                    >
                        <Form.Item
                            name="codeType"
                            initialValue="javascript"
                            rules={[{
                                validator: onFinishCodeType
                            }]}
                        >
                            <Select placeholder="choose language">
                            <Option value="javascript">javascript</Option>
                            <Option value="java">java</Option>
                            <Option value="cpp">cpp</Option>
                            </Select>
                        </Form.Item>
                    </Form>
                    <Button type='primary' onClick={initCode} style={{
                        marginLeft: "20px"
                    }}>初始化代码</Button>
                </div>
                <div className='codeResult'>
                    <div className='codeResult-box'>
                        <div className='header'>
                            <div>代码执行结果：</div>
                            {
                                pending ?<><span className='pending'>pending</span> <ReactLoading className='pending-circle' type='spin' color='#2b6cd3' height={20} width={20}></ReactLoading></>
                                :!codeResult.data && !codeResult.err ? "" :
                                codeResult.data ? 
                                <span className='finished'>Finished</span>:
                                <span className='failed'>Failed</span>
                            }
                        </div>
                        <div className='text'>
                            输出
                        </div>
                        <div className='output' dangerouslySetInnerHTML={{__html: codeResult.data ? parseResult(codeResult.data) : parseResult(codeResult.err)}}></div>
                    </div>
                </div>
            </div>
        </div>
    )
}
